package foliotracker.GUI;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import foliotracker.Portfolio;
import foliotracker.PortfolioCollection;
import foliotracker.Stock;
import foliotracker.controllers.BuyStockController;
import foliotracker.controllers.FolioTrackerController;
import foliotracker.controllers.PortfolioCollectionController;
import foliotracker.controllers.SellStockController;
import foliotracker.views.IFolioTrackerView;
import foliotracker.views.IPortfolioHistoryView;
import foliotracker.views.IPortfolioView;
import foliotracker.views.IStockView;



public class MainWindow extends JFrame implements IFolioTrackerView
{
	private static final long serialVersionUID = 1L;
	private JToolBar toolBar;
	private JTabbedPane tabs;
	private FolioTrackerController controller;
	private JButton addStockButton,removeStockButton, historyButton;
	private ProgressDialog progressDialog;
	private JMenuBar menuBar;
	private JMenu mainMenu;
	private JMenuItem closeTabMenu;
	
	public MainWindow(FolioTrackerController controller)
	{
		super("FolioTracker");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		initialiseComponents();
		
		this.controller = controller;
	}
	
	
	private void initialiseComponents()
	{
		JPanel contentPane = (JPanel)getContentPane();
		contentPane.setBorder(new EmptyBorder(6, 6, 6, 6));
		setSize(650, 300);
		setMinimumSize(new Dimension(650, 300));
		final JFrame window = this;
		
		/************************************
         * Action listeners                 *
         ************************************/
		ActionListener newPortfolioListener = new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent event)
			{
				controller.newPortfolio();
			}
		};
		
		ActionListener addStockListener = new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent event)
			{
				IPortfolioView view = (IPortfolioView)tabs.getSelectedComponent();
				BuyStockController buyController = new BuyStockController(view.getPortfolio());
				openBuyStockView(buyController);
			}
		};
		
		
		
		ActionListener updateListener = new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent event)
			{
				EventQueue.invokeLater(new Runnable()
				{
					@Override
					public void run()
					{
						controller.updatePrices();
					}
				});
			}
		};
		
		ActionListener deleteListener = new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent event)
			{
				IPortfolioView view = (IPortfolioView)tabs.getSelectedComponent();
				SellStockController sellController = new SellStockController(view.getPortfolio());
				openSellStockView(sellController);
			}
		};
		
		ActionListener newFileListener = new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent event)
			{
				controller.newFile();
			}
		};
		
		ActionListener loadFileListener = new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent event)
			{
				JFileChooser chooser  = new JFileChooser(System.getProperty("user.dir"));
				
				if (chooser.showOpenDialog(window) == JFileChooser.APPROVE_OPTION)
				{
					controller.load(chooser.getSelectedFile().getAbsolutePath());
				}
			}
		};
		
		ActionListener saveFileListener = new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent event)
			{
				JFileChooser chooser  = new JFileChooser(System.getProperty("user.dir"));
				
				if (chooser.showSaveDialog(window) == JFileChooser.APPROVE_OPTION)
				{
					controller.save(chooser.getSelectedFile().getAbsolutePath());
				}
			}
		};
		
		ActionListener closeTabListener = new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent event)
			{
				tabs.remove(tabs.getSelectedComponent());
			}
		};
		
		ActionListener historyListener = new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent event)
			{
				IPortfolioView view = (IPortfolioView)tabs.getSelectedComponent();
				openPortfolioHistoryView(view.getPortfolio());
			}
		};
		
		/************************************
         * MenuBar			                *
         ************************************/
		
		mainMenu = new JMenu("File");
		menuBar = new JMenuBar();
		addMenuItem(mainMenu, "New", "control N", newFileListener);
		addMenuItem(mainMenu, "Save", "control S", saveFileListener);
		addMenuItem(mainMenu, "Open", "control O", loadFileListener);
		
		mainMenu.addSeparator();
		closeTabMenu = addMenuItem(mainMenu, "Close tab", "control W", closeTabListener);
		
		menuBar.add(mainMenu);
		this.setJMenuBar(menuBar);
		
		/************************************
         * Toolbar                          *
         ************************************/
		toolBar = new JToolBar();
		contentPane.add(toolBar, BorderLayout.PAGE_START);
		addButton("new.png", "New portfolio", newPortfolioListener);
		addButton("refresh.png", "Update prices", updateListener);
		addStockButton = addButton("add.png", "Buy stock", addStockListener);
		removeStockButton = addButton("delete.png", "Sell stock", deleteListener);
		historyButton = addButton("graph.png", "History", historyListener);
		
		/************************************
         * Tabs                             *
         ************************************/
		
		tabs = new JTabbedPane();
		contentPane.add(tabs, BorderLayout.CENTER);
		tabs.addChangeListener(new ChangeListener()
		{
			@Override
			public void stateChanged(ChangeEvent e)
			{
				 Component sourceTabbedPane = ((JTabbedPane)e.getSource()).getSelectedComponent();
			     if(sourceTabbedPane instanceof PortfolioView){
			    	 addStockButton.setVisible(true);
			    	 removeStockButton.setVisible(true);
			    	 historyButton.setVisible(true);
			     }
			     else
			     {
			    	 addStockButton.setVisible(false);
			    	 removeStockButton.setVisible(false);
			    	 historyButton.setVisible(false);
			     }
			     
			     if (sourceTabbedPane instanceof PortfolioCollectionView)
			     {
			    	 closeTabMenu.setVisible(false);
			     }
			     else
			     {
			    	 closeTabMenu.setVisible(true);
			     }
			}
		});

		
		
	}
	
	
	/**
     * Adds a new button to the toolbar.
     * @param image A URL to the icon on the button.
     * @param text The text to be displayed next to the button.
     * @param actionListener The ActionListener to be executed when the button is clicked.
     * @return The newly-created button.
     */
    private JButton addButton(String image, String text, ActionListener actionListener)
    {
        JButton button = new JButton();
        button.setToolTipText(text);
        ImageIcon icon = new ImageIcon("resources/images/" + image);
        
        button.setIcon(icon);
        button.setBorderPainted(false);
        button.setFocusPainted(false);
        button.setText(text);
        button.addActionListener(actionListener);
        toolBar.add(button);

        return button;
    }
    
    private JMenuItem addMenuItem(JMenu parent, String text, String accelerator, ActionListener actionListener){
    	
    	JMenuItem item = new JMenuItem(text);
    	
    	if (accelerator != null)
    		item.setAccelerator(KeyStroke.getKeyStroke(accelerator));
    	
    	parent.add(item);
    	item.addActionListener(actionListener);
    	return item;
    }

	@Override
	public void showError(String message) {
		JOptionPane.showMessageDialog(this,message);
		
	}


	@Override
	public void closeOpenDocuments() {
		tabs.removeAll();
		
	}


	@Override
	public void openPortfolioCollectionView(PortfolioCollectionController controller, PortfolioCollection collection)
	{

		PortfolioCollectionView view  = new PortfolioCollectionView(this, collection);
		controller.setView(view);
		tabs.addTab("Portfolios",view);
	}


	@Override
	public void updatePercentageComplete(int percentage)
	{
		if (percentage < 100)
		{
			if (progressDialog == null)
			{
				progressDialog = new ProgressDialog();
				progressDialog.setVisible(true);
			}
			
			progressDialog.update(percentage);
		}
		else if (progressDialog != null)
		{
			progressDialog.setVisible(false);
			progressDialog = null;
		}
	}


	@Override
	public void openPortfolioView(Portfolio portfolio)
	{
		for (Component c: tabs.getComponents())
		{
			if (c instanceof IPortfolioView)
			{
				if (((IPortfolioView)c).getPortfolio() == portfolio)
				{
					tabs.setSelectedComponent(c);
					return;
				}
			}
		}
		
		PortfolioView view  = new PortfolioView(this, portfolio);
		tabs.addTab(portfolio.getName(), view);
		tabs.setSelectedComponent(view);
	}


	@Override
	public void openBuyStockView(BuyStockController buy) {
		
		BuyStockDialog dialog = new BuyStockDialog(buy);
		buy.setView(dialog);
		dialog.setVisible(true);
	}


	@Override
	public void openSellStockView(SellStockController sell) {
		
		SellStockDialogue dialog = new SellStockDialogue(sell);
		sell.setView(dialog);
		dialog.setVisible(true);
		
	}
	
	
	@Override
	public void openStockView(Stock stock)
	{
		for (Component c: tabs.getComponents())
		{
			if (c instanceof IStockView)
			{
				if (((IStockView)c).getStock() == stock)
				{
					tabs.setSelectedComponent(c);
					return;
				}
			}
		}
		
		StockView view = new StockView(stock);
		tabs.addTab(stock.getName(), view);
		tabs.setSelectedComponent(view);
	}
	
	
	public void openPortfolioHistoryView(Portfolio portfolio)
	{
		for (Component c: tabs.getComponents())
		{
			if (c instanceof IPortfolioHistoryView)
			{
				if (((IPortfolioHistoryView)c).getPortfolio() == portfolio)
				{
					tabs.setSelectedComponent(c);
					return;
				}
			}
		}
		
		PortfolioHistoryView view  = new PortfolioHistoryView(portfolio);
		tabs.addTab(portfolio.getName() + " history", view);
		tabs.setSelectedComponent(view);
	}
}
